unit Dos.ORM.Field;

interface

uses
  Data.DB, Dos.ORM.GroupByClip, Dos.ORM.OrderByClip, System.SysUtils;

type
  TField = class
  private
    FFieldName: string;
    FTableName: string;
    FAliasName: string;
    FDescription: string;
    FParameterDbType: TFieldType;
    FParameterSize: Integer;
  public
    constructor Create(); overload;
    constructor Create(fieldName: string); overload;
    constructor Create(fieldName, tableName: string); overload;
    constructor Create(fieldName, tableName, description: string); overload;
    constructor Create(fieldName, tableName: string; parameterDbType: TFieldType; parameterSize: Integer; description: string); overload;
    constructor Create(fieldName, tableName: string; parameterDbType: TFieldType; parameterSize: Integer; description, aliasName: string); overload;
    function FieldAs(aliasName: string): TField; overload;
    function Name: string;
    function FieldAs(Field: TField): TField; overload;
    function TableFieldName: string;
    function FullName: string;
    function ParameterDbType: TFieldType;
    function ParameterSize: Integer;
    function SetTableName(tableName: string): TField;
    function TableName: string;
    function PropertyName: string;
    function Description: string;
    function Year(): TField;
    function Month(): TField;
    function Day: TField;
    function GroupBy: TGroupByClip;
    function Asc(): TOrderByClip;
    function Desc(): TOrderByClip;
    function Count(): TField;
    function Distinct(): TField;
    function Sum(): TField;
    function Avg(): TField;
    function Len(): TField;
    function Trim(): TField;
    function Max(): TField;
    function Min(): TField;
    function Left(length: Integer): TField;
    function Right(length: integer): TField;
    function Substring(startIndex, endIndex: Integer): TField;
    function IndexOf(subString: string): TField;
    function Replace(oldValue, newValue: string): TField;
  public
  end;

  TFields = array of TField;

implementation

{ Field }

constructor TField.Create(fieldName, tableName: string);
begin
  FFieldName := fieldName;
  FTableName := tableName;
end;

constructor TField.Create(fieldName: string);
begin
  FFieldName := fieldName;
end;

constructor TField.Create;
begin

end;

function TField.Asc: TOrderByClip;
begin
  Result := TOrderByClip.Create(self.FFieldName, OrderByOperater.ASC);
end;

function TField.Avg: TField;
begin
  Result := TField(Concat('avg(', self.TableFieldName, ')')).FieldAs(self);
end;

function TField.Count: TField;
begin
  if Self.PropertyName.Trim.Equals('*') then
    Result := TField.Create('count(*)').FieldAs('cnt')
  else
    Result := TField.Create(Concat('count(', self.TableFieldName, ')')).FieldAs(self);
end;

constructor TField.Create(fieldName, tableName: string; parameterDbType: TFieldType; parameterSize: Integer; description, aliasName: string);
begin
  FFieldName := fieldName;
  FTableName := tableName;
  FparameterDbType := parameterDbType;
  FparameterSize := parameterSize;
  Fdescription := description;
  FaliasName := aliasName;
end;

function TField.Day: TField;
begin
  Result := TField.Create(Concat('datepart(Day,', Self.TableFieldName, ')'));
  Result := Self.FieldAs(Result);
end;

function TField.Desc: TOrderByClip;
begin
  Result := TOrderByClip.Create(self.FFieldName, OrderByOperater.Desc);
end;

function TField.Description: string;
begin
  Result := FDescription;
end;

function TField.Distinct: TField;
begin
  if (self.PropertyName.Trim().Equals('*')) then
    Result := Self
  else
    Result := TField.Create(Concat('distinct ', self.TableFieldName)).FieldAs(self);
end;

constructor TField.Create(fieldName, tableName: string; parameterDbType: TFieldType; parameterSize: Integer; description: string);
begin
  FFieldName := fieldName;
  FTableName := tableName;
  FparameterDbType := parameterDbType;
  FparameterSize := parameterSize;
  Fdescription := description;
end;

constructor TField.Create(fieldName, tableName, description: string);
begin
  FFieldName := fieldName;
  FTableName := tableName;
  Fdescription := description;
end;

function TField.FieldAs(aliasName: string): TField;
begin
  Result := TField.Create(self.FfieldName, Self.ftableName, self.FparameterDbType, self.FparameterSize, self.Fdescription, aliasName);
end;

function TField.FieldAs(Field: TField): TField;
begin
  Result := Self.FieldAs(Field.Name);
end;

function TField.FullName: string;
begin
  if FAliasName = '' then
    Result := TableFieldName
  else
    Result := Concat(TableFieldName, ' AS ', FAliasName);
end;

function TField.GroupBy: TGroupByClip;
begin
  result := TGroupByClip(self.FFieldName);
end;

function TField.IndexOf(subString: string): TField;
begin
  Result := TField.Create(Concat('charindex(', self.TableFieldName, ',', subString.QuotedString, ')')).FieldAs(self);
end;

function TField.Left(length: Integer): TField;
begin
  Result := TField.Create(Concat('left(', self.TableFieldName, ',', length.ToString(), ')')).FieldAs(self);
end;

function TField.Len: TField;
begin
  Result := TField.Create(Concat('len(', self.TableFieldName, ')')).FieldAs(self);
end;

function TField.Max: TField;
begin
  Result := TField.Create(Concat('max(', self.TableFieldName, ')')).FieldAs(self);
end;

function TField.Min: TField;
begin
  Result := TField.Create(Concat('min(', self.TableFieldName, ')')).FieldAs(self);
end;

function TField.Month: TField;
begin
  Result := TField.Create(Concat('datepart(month,', Self.TableFieldName, ')'));
  Result := Self.FieldAs(Result);
end;

function TField.Name: string;
begin
  if FAliasName = '' then
    Result := FFieldName
  else
    Result := FAliasName;
end;

function TField.ParameterDbType: TFieldType;
begin
  Result := self.FParameterDbType;
end;

function TField.ParameterSize: Integer;
begin
  Result := self.FParameterSize;
end;

function TField.PropertyName: string;
begin
  Result := FFieldName;
end;

function TField.Replace(oldValue, newValue: string): TField;
begin
  Result := TField.Create(Concat('replace(', self.TableFieldName, ',', oldValue.QuotedString, ',', newValue.QuotedString, ')')).FieldAs(self);
end;

function TField.Right(length: integer): TField;
begin
  Result := TField.Create(Concat('right(', self.TableFieldName, ',', length.ToString(), ')')).FieldAs(self);
end;

function TField.SetTableName(tableName: string): TField;
begin
  Result := TField.Create(self.FfieldName, tableName, self.FparameterDbType, self.FparameterSize, self.Fdescription, self.FaliasName);
end;

function TField.Substring(startIndex, endIndex: Integer): TField;
begin
  Result := TField.Create(Concat('substring(', self.TableFieldName, ',', startIndex.ToString(), ',', endIndex.ToString(), ')')).FieldAs(self);
end;

function TField.Sum: TField;
begin
  Result := TField.Create(Concat('sum(', self.TableFieldName, ')')).FieldAs(self);
end;

function TField.TableFieldName: string;
begin
  if FTableName = '' then
    Result := FFieldName
  else
    Result := Concat(FTableName, '.', FFieldName);
end;

function TField.TableName: string;
begin
  result := self.FTableName;
end;

function TField.Trim: TField;
begin
  Result := TField.Create(Concat('ltrim(rtrim(', self.TableFieldName, '))')).FieldAs(self);
end;

function TField.Year: TField;
begin
  Result := TField.Create(Concat('datepart(year,', Self.TableFieldName, ')'));
  Result := Self.FieldAs(Result);
end;

end.

